;
;
SdRsp.ssckt equ 4
SdRsp.dnet equ 5
SdRsp.dnode equ 7
SdRsp.dsckt equ 8
SdRsp.flag equ 9
SdRsp.bitmap equ 10
SdRsp.tid equ 11
SdRsp.bdsadr equ 13
SdRsp.bdssiz equ 15
SdRsp.timer equ 16
;
GetRq.dsckt equ 4
GetRq.snet equ 5
GetRq.snode equ 7
GetRq.ssckt equ 8
GetRq.flag equ 9
GetRq.bitmap equ 10
GetRq.tid equ 11
GetRq.bdsadr equ 13
GetRq.nxtptr equ 16
;
;
ATPXObit equ $20
ATPEOMbit equ $10
ATPSTSbit equ $08
ATPchksum equ $01
;
OpenATPSckt equ *
 ldx #>atprplisten
 ldy #<atprplisten
 jmp getnscktno
;
;
;
AtpSndResponse equ *
 php
 sei ; non-rentrant code does not allow interrupt
 ldy #SdRsp.ssckt
 lda (cmndlist),y
 jsr chkvalidsckt ; is it valid ?
 bne retasynflag ; bad socket error
 ldy #GetRq.bitmap
 lda (cmndlist),y ; get buffer to be sent
 jsr sendNrsp ; send the N response
 pha ; save error flag
 jsr FindRspCBIndex ; see if RspCB exists
 bpl Asndrsp.9 ; yes, wait for release
 pla ; not XO, get back error flag
 jmp retasynflag ; and return it
Asndrsp.9 pla ; pop error flag and ignore it
 ldy #SdRsp.timer
 lda #120 ; 30 sec
 sta (cmndlist),y ; also reset timer
waitdone lda #$80 ; first indicates it is busy
retasynflag ldy #1
 sta (cmndlist),y
 ora #0 ; Get status.
 bpl procdone ; if error or request complete call io complete routine.
 plp ; re-enable interrupt, otherwise wait for ever
 dey ; check for async
 lda (cmndlist),y
 bmi waitdn.9 ; Branch if async done.
 iny
waitdn.1 equ *
 lda (cmndlist),y
 bmi waitdn.1
 sta status
waitdn.9 equ *
 rts
;
;
procdone plp  ; re-enable interrupts.
chkiocmp ldy #0
 lda (cmndlist),y
 bpl waitdn.9 ; no need if not asyn
 iny
 lda (cmndlist),y
 bmi waitdn.9 ; not yet completed
 iny
 lda (cmndlist),y
 sta execadr
 iny
 lda (cmndlist),y
 sta execadr+1
 beq waitdn.9 ; no completition routine
 IFNE OPERS-PRODOS
 ldx cmndlist
 ldy cmndlist+1
 FIN
; fall thru to doexecute
;
; since execadr is in zero page, it will be saved and restore during interrupt
; and it can be resued after the jmp indirect
doexecute jmp (execadr)
;
;
AGetRequest equ *
 jsr killRspCB ; not needed, only as a caution against user mistake
 php
 sei
 ldy #GetRq.dsckt
 lda (cmndlist),y ; get socket number
 jsr chkvalidsckt ; is it valid ?
 bne retasynflag ; bad socket error
 ldy #GetRq.nxtptr+1
 lda #0
 sta (cmndlist),y ; zero it to make sure it is end of queue
 txa
 asl a
 tax
 lda atprptable+1,x
 beq getreq.3
 sta atprqptr+1
 lda atprptable,x
 sta atprqptr
 DO SAFECLOSE
getreq.1 jsr nextinqueue ; find end of queue
 bne getreq.1 ; bra because y <> 0
 ELSE
getreq.1 ldy #GetRq.nxtptr+1
 lda (atprqptr),y
 beq getreq.2
 tax
 dey
 lda (atprqptr),y
 sta atprqptr
 stx atprqptr+1
 jmp getreq.1
 FIN
getreq.2 lda cmndlist+1
 sta (atprqptr),y
 lda cmndlist
 dey ; also clear Z flag
 sta (atprqptr),y
 bne waitdone ; BRA
getreq.3 lda cmndlist
 sta atprptable,x
 lda cmndlist+1
 sta atprptable+1,x
 bne waitdone ; BRA
;
 DO SAFECLOSE
nextinqueue ldy #GetRq.nxtptr+1
 lda (atprqptr),y
 beq nxtq.9
 tax
 dey
 lda (atprqptr),y
 sta atprqptr
 stx atprqptr+1
 iny ; point back to low byte, also clear Z flag
nxtq.9 rts
 FIN
;
;
FindRspCBIndex equ * ; return index into RspCBTable
 ldx #RspCBend ; check for RspCB
 lda #RspCBbegin
FindTable sta fRsp.2+1
fRsp.1 dex
 dex
fRsp.2 cpx #0 ; self modifying code
 bmi fRsp.9
 lda cmndlist
 cmp processtable,x
 bne fRsp.1
 lda cmndlist+1
 cmp processtable+1,x
 bne fRsp.1
fRsp.9 rts ;
;
atprplisten equ * ; listener for reply
 jsr rdatpheader ; read header and calculate checksum
 bne fRsp.9 ; error, return with carry flag clear
 lda atpheader
 tax
 asl a ; check function
 bpl secrts ; request, ignore it
 bcs atprpls.3 ; release ; release XO
 txa
 and #ATPXObit
 beq atprpls.4 ; not XO
 jsr LookRspCB ; check for duplicate
 sta atprpls.4a+1
 bmi atprpls.4 ; no, do it the normal way
 ldy #1
 lda (cmndlist),y ; are we ready ?
 bpl secrts ; no
; potential bug, we may need to check more
 lda atpheader+1 ; any request ?
 beq secrts ; no, ignore it
 ldy #SdRsp.bitmap
 and (cmndlist),y ; find repsonse needed
 beq *+5
 jmp sendNrsp
 lda #requestfail ; none of the request is available
 bne retasynsec ; BRA to return as error
atprpls.3 jsr LookRspCB ; is it in table ?
 bmi secrts ; no, ignore it
 tax
 lda #0 ; also set error to 0
 sta processtable+1,x ; remove item from table
retasynsec ldy #1 ; return asyn result byte and also set carry
 sta (cmndlist),y
 jsr chkiocmp
secrts sec
 rts
atprpls.4 lda ddphead+ld.dsckt ; address to which socket
 jsr srchscktable
;bne secrts ; discard it, actually this is not possible
 txa
 asl a
 tax
 lda atprptable+1,x ; anything queue up ?
 beq secrts ; no discard it
 sta cmndlist+1
 lda atprptable,x
 sta cmndlist
 stx atprpls.5+1 ; save x reg for use later
 lda #0 ; it is the first bds
 ldy #GetRq.bdsadr
 jsr readltdsize
 bne atprpls.8 ; checksum error, do not use it
 lda atpheader
 and #ATPXObit ; is it XO ?
 beq atprpls.5 ; then no need to generate Rsp CB
atprpls.4a lda #0 ; self modifying code, do we have one already
;
; note this is OK now, but if we ever change the process table
;   then we may have a bug
;
 bne atprpls.5 ; we already have a Rsp CB
 ldy #RspCBSize*2
atprpls.4b dey
 dey
 bmi atprpls.8 ; don't do it unless we have room for Rsp CB
 lda RspCBTable+1,y
 bne atprpls.4b
 lda cmndlist ; create a RspCB
 sta RspCBTable,y
 lda cmndlist+1
 sta RspCBTable+1,y
atprpls.5 ldx #0 ; self modifying code
 ldy #GetRq.nxtptr ; remove front item from queue
 lda (cmndlist),y
 sta atprptable,x
 iny
 lda (cmndlist),y
 sta atprptable+1,x
 ldy #GetRq.snet
atprpls.5a ldx RspCmptable+1-GetRq.snet,y
 beq atprpls.5b
 lda dataarea,x
 sta (cmndlist),y
 iny
 bne atprpls.5a ; BRA
atprpls.5b ldy #GetRq.flag
atprpls.5c lda atpheader-GetRq.flag,y
 sta (cmndlist),y
 iny
 cpy #GetRq.tid+2
 bne atprpls.5c
 lda #0
 ldy #1
 sta (cmndlist),y
 jsr chkiocmp
atprpls.8 clc ; indicate we have processed it
 rts
;
LookRspCB equ *
 lda #RspCBend
 ldx #RspCBbegin
 ldy #ddphead+ld.snet-dataarea ; must check network number
 sty RspCmptable+1
 iny
 sty RspCmptable+2
Looktable pha ; save index
 stx lkrsp.2+1
lkrsp.1 pla
 tax
 dex
 dex
 txa
lkrsp.2 cpx #0
 bmi lkrsp.5 ; return with N set
 pha
 lda processtable,x
 sta CmndList
 lda processtable+1,x
 sta CmndList+1
 beq lkrsp.1 ; empty, try next
 ldy #SdRsp.ssckt-1 ; coming from right address ?
lkrsp.3 iny
 ldx RspCmptable-SdRsp.ssckt,y
 beq lkrsp.3 ; don't care
 bmi lkrsp.4 ; end of list marker, this is it
 lda (CmndList),y
 cmp dataarea,x
 beq lkrsp.3 ; agree, then check more
 bne lkrsp.1 ; no, try again
lkrsp.4 pla ; since acc is always positive, return with N clear
lkrsp.5 rts
;
RspCmptable equ *
 dfb ddphead+ld.dsckt-dataarea
 dfb ddphead+ld.snet-dataarea
 dfb ddphead+ld.snet+1-dataarea
 dfb ddphead+ld.snode-dataarea
 dfb ddphead+ld.ssckt-dataarea
 dfb 0,0
 dfb atpheader+2-dataarea
 dfb atpheader+3-dataarea
 dfb -1
;
;
;
;
sendNrsp equ *
 pha ; save the bit map to be sent
 lda #$80 ; response packet
 sta atpheader
 lda #$FF
 sta atpheader+1 ; start with response -1
sdrsp.1 pla ; get back bit map to be sent
 beq sdrsp.9 ; done
 inc atpheader+1
 lsr a ; move bit to carry
 pha
 bcc sdrsp.1 ; this buffer not needed
 bne sdrsp.2 ; not last buffer in sequence
 ldy #SdRsp.flag
 lda (cmndlist),y
 and #ATPSTSbit
 ora atpheader
 sta atpheader
sdrsp.2 lda atpheader+1
 tax
 adc #0 ; since carry is set (else bcc sdrsp.1), we increment acc by 1
 ldy #SdRsp.bdssiz
 cmp (cmndlist),y ; is this EOM
 bcc sdrsp.3 ; not last, just send it
 bne sdrsp.1 ; not smaller or equal, then too big
 ldy #SdRsp.flag ; equal to last, then may need EOM
 lda (cmndlist),y
 and #ATPEOMbit
 ora atpheader
 sta atpheader
sdrsp.3 txa
 asl a ; * 2
 asl a ; * 4
 adc atpheader+1 ; *5
 asl a ; * 10
 jsr watppckt ; send an ATP packet
 beq sdrsp.1 ; no error
 tax ; save error
 pla ; pop stack
 txa ; get back error
sdrsp.9 sec ; always return with carry set for cortland compatabliity
 rts
;
;
;
killRspCB php
 sei
 jsr FindRspCBIndex ; see if RspCB exists
 bmi *+7
 lda #0
 sta processtable+1,x ; remove item from table
 plp
 rts
